% demo_superbar
%
% In this tutorial, we demonstrate how to use SUPERBAR. We begin with the
% most basic usage, and show how the same code for BAR can be achieved
% using SUPERBAR.

% Make a figure to put the example plots into
figure;


%% ========================================================================
%. (1) Bars by themselves
%. ========================================================================

% In the first section, we demonstrate usage of SUPERBAR when used just for
% plotting bars.

%% Plot a few bars
clf;

Y = [11 15 12.5 9];

% Plot with bar
subplot(1, 2, 1);
bar(Y);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y);
title('superbar');

% The result is almost the same, but the default colour for SUPERBAR is
% grey instead of blue.
% Notice that BAR changes the XTICK values for the axes it is plotted on,
% whereas SUPERBAR leaves them be.


%% Plot a few bars, with manual X-locations
clf;

Y = [11 15 12.5 9 ];
X = [10 20 30   50];

% Plot with bar
subplot(1, 2, 1);
bar(X, Y);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(X, Y);
title('superbar');

% For both BAR and SUPERBAR, the default bar width is based on the minimum
% separation between the X-values.


%% Changing the width of the bars
clf;

Y = [11 15 12.5 9 ];
X = [10 20 30   50];

% Plot with bar
subplot(1, 2, 1);
bar(X, Y, 0.5);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(X, Y, 'BarWidth', 5);
title('superbar');

% Bar width can be adjusted as necessary. For BAR, the width parameter
% controls the scaling of the bar widths relative to the minimum spacing
% between the bars. For SUPERBAR, the 'BarWidth' keyword parameter provides
% a literal value for the bar width instead of a relative value.


%% Plot 2 groups each containing 3 bars
clf;

Y = [11 14 13;
     15 12 16];

% Plot with bar
subplot(1, 2, 1);
bar(Y);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y);
title('superbar');

% Notice how the bars are different widths in the two versions.
% If you want to control the width of the group of bars in SUPERBAR, you
% can do so by manipulating the 'BarWidth' parameter again. For group
% plots, 'BarWidth' is the width of the group instead of a single bar.
% The width of the bars within the group can be specified with the
% 'BarRelativeGroupWidth' keyword parameter.


%% ... matching group bar widths from SUPERBAR to BAR

% Plot with superbar
cla;
superbar(Y, ...
    'BarWidth', 0.665);
% xlim([0.5 2.5]);
title('superbar');

% It happens that a 'BarWidth' of around 0.665, will approximately match
% the widths of bars in SUPERBAR to be the same as in BAR, provided the X
% locations of the bars are sequential integers (1, 2, 3, ...).


%% Plot each bar series in a different colour
clf;

Y = [11 14 13;
     15 12 16];
C = [.8 .2 .2;
     .2 .8 .2;
     .2 .2 .8];

% Plot with bar
subplot(1, 2, 1);
h = bar(Y);
for iBarSeries = 1:size(Y,2)
    set(h(iBarSeries), 'FaceColor', C(iBarSeries, :), 'EdgeColor', 'none');
end
xlim([0.5 2.5]);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'BarFaceColor', permute(C, [3 1 2]));
% We have to permute C so that the first dimension is singleton, indicating
% since the first dimension of Y is the group and we want the same colour
% in each group. The second dimension, which is for the series in Y and
% also C, we will have 3 values (one for each series), and the final (3rd)
% dimension will be for the colour channel.
xlim([0.5 2.5]);
title('superbar');

% We can get the same result in each case, but we need to loop over the
% bar handles to fix the colours generated by BAR; there is no way to set
% these as an input argument or all at once.


%% Hollow bars
clf;

Y = [11 14 13;
     15 12 16];

% Plot with bar
subplot(1, 2, 1);
h = bar(Y);
for iBarSeries = 1:size(Y,2)
    set(h(iBarSeries), 'FaceColor', 'none');
end
xlim([0.5 2.5]);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'BarFaceColor', 'none');
xlim([0.5 2.5]);
title('superbar');

% You can also have hollow bars, if you like.


%% Coloured hollow bars
clf;

Y = [11 14 13;
     15 12 16];
C = [.8 .2 .2;
     .2 .8 .2;
     .2 .2 .8];

% Plot with bar
subplot(1, 2, 1);
h = bar(Y);
for iBarSeries = 1:size(Y,2)
    set(h(iBarSeries), 'FaceColor', 'none', 'EdgeColor', C(iBarSeries, :));
end
xlim([0.5 2.5]);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'BarFaceColor', 'none', 'BarEdgeColor', permute(C, [3 1 2]));
xlim([0.5 2.5]);
title('superbar');

% Or hollow with a coloured outline.


%% Plot each bar group in a different colour
clf;

Y = [11 14 13;
     15 12 16];
C = [.8 .2 .8;
     .2 .75 .2];

% Plot with bar
subplot(1, 2, 1);
text(0.5, 0.5, 'not implemented', 'HorizontalAlignment', 'center');
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'BarFaceColor', C);
% We don't have to permute C anymore because we now want to differentiate
% the colours by group. The final dimension of C is the colour channel.
xlim([0.5 2.5]);
title('superbar');

% Using SUPERBAR, we can easily set each group to have its own colour. This
% cannot be done with BAR


%% Plot each individual bar group in a unique colour
clf;

Y = [11 14 13;
     15 12 16];

C = nan(2, 3, 3);
C(1, 1, :) = [.9 .3 .3];
C(1, 2, :) = [.3 .9 .3];
C(1, 3, :) = [.3 .3 .9];
C(2, 1, :) = [.6 .1 .1];
C(2, 2, :) = [.1 .6 .1];
C(2, 3, :) = [.1 .1 .6];

% Plot with bar
subplot(1, 2, 1);
text(0.5, 0.5, 'not implemented', 'HorizontalAlignment', 'center');
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'BarFaceColor', C);
% C needs to be a 3 dimensional array, with first dimension the group,
% second the series, and third (final) dimension the colour channel.
xlim([0.5 2.5]);
title('superbar');

% Using SUPERBAR, we can easily set each group to have its own colour. This
% cannot be done with a single call to BAR.


%% Stacked bars - not implemented in SUPERBAR
clf;

Y = [11 14 13;
     15 12 16];

% Plot with bar
subplot(1, 2, 1);
bar(Y, 'stacked');
xlim([0.5 2.5]);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
text(0.5, 0.5, 'not implemented', 'HorizontalAlignment', 'center');
title('superbar');

% Please note that you can't plot stacked bars in SUPERBAR.


%% Horizontal bars
clf;

Y = [11 14 13;
     15 12 16];

% Plot with bar
subplot(1, 2, 1);
barh(Y);
ylim([0.5 2.5]);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'Orientation', 'h');
ylim([0.5 2.5]);
title('superbar');

% Horizontal bars can not be done with BAR and must be created using the
% function BARH instead. With SUPERBAR, plot orientation is changed by
% using the 'Orientation' keyword parameter and setting this to 'h' or
% 'horizontal'.
% In both cases, everything mentioned so far can be done for either
% vertical or horizontal bars.


%% Change other bar properties
clf;

Y = [11 14 13;
     15 12 16];

% Plot with bar
subplot(1, 2, 1);
bar(Y, 'LineWidth', 3);
xlim([0.5 2.5]);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
h = superbar(Y, 'BarEdgeColor', 'k');
set(h, 'LineWidth', 3);
xlim([0.5 2.5]);
title('superbar');

% Other bar properties currently can not be passed to superbar. To specify
% these, one must capture the handles to the bars output by SUPERBAR and
% then change the properties.
% (In a future release of SUPERBAR, it will also be possible to specify
% these properties as part of the call to the function.)


%% ========================================================================
%. (2) Bars with errors
%. ========================================================================

% In this section, we describe how SUPERBAR can be used to plot bars with
% errors, and compare this to using BAR accompanied with ERRORBAR.

%% Bars with error bars
clf;

Y = [11 15 12.5 9];
E = [ 3  4  2   1.5];

% Plot with bar
subplot(1, 2, 1);
hold on;
bar(Y);
errorbar(Y, E, '.', 'MarkerSize', 1);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'E', E);
title('superbar');

% BAR does not support error bars, but the builtin ERRORBAR function can
% be used to provide them.
% SUPERBAR supports error bars natively, via calls to the SUPERERR
% companion function, which also works independently of SUPERBAR.


%% Bars with error bars
clf;

Y = [11 15 12.5 9];
C = [.8 .3 .8];
E = [ 3  4  2   1.5];
CE = [.5 .1 .5];

% Plot with bar
subplot(1, 2, 1);
hold on;
bar(Y, 'FaceColor', C, 'EdgeColor', 'none');
errorbar(Y, E, '.', 'MarkerSize', 1, 'Color', CE);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'BarFaceColor', C, 'E', E, 'ErrorbarColor', CE);
title('superbar');

% Provided all bars should be in the same colour, the colour can be
% customised in either case.


%% Horizontal bars with error bars
clf;

Y = [11 15 12.5 9  ];
E = [ 3  4  2   1.5];

% Plot with bar
subplot(1, 2, 1);
hold on;
text(0.5, 0.5, 'not implemented', 'HorizontalAlignment', 'center');
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'E', E, 'Orientation', 'h');
title('superbar');

% Since ERRORBAR is only for vertical error bars, there is no way to get
% horizontal error bars with builtin functions.
% SUPERERR supports both X and Y error bars, so SUPERBAR does too.


%% Grouped bars with errorbars
clf;

Y = [11 14 13;
     15 12 16];
E = [ 3  4  2;
      5  2  3];

% Plot with bar
subplot(1, 2, 1);
text(0.5, 0.5, 'not implemented', 'HorizontalAlignment', 'center');
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'E', E);
title('superbar');

% Since one does not know the X locations of the individual bars, BAR and
% ERRORBAR can not be used together to add error bars to grouped bar plots.


%% Upward only errorbars
clf;

Y = [11 15 12.5 9  ];
E = [ 3  4  2   1.5];

% Plot with bar
subplot(1, 2, 1);
hold on;
bar(Y);
h = errorbar(1:numel(Y), Y(:), zeros(size(E)), E, '.', 'MarkerSize', 1);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'E', E, 'ErrorbarStyle', 'T');
title('superbar');

% With a little effort, upward only errorbars can be achieved with
% builtins.
% With SUPERBAR, the error bar style can be changed with the
% 'ErrorbarStyle' keyword parameter.

%% ... other styles can be set for SUPERBAR - no caps symmetric
cla;
superbar(Y, 'E', E, 'ErrorbarStyle', '|');

%% ... other styles can be set for SUPERBAR - no caps and upward only
cla;
superbar(Y, 'E', E, 'ErrorbarStyle', '''');
% The peculiar code '''' is needed in MATLAB to encode a single quote
% character. A single quote is the error bar style for

%% ... other styles can be set for SUPERBAR - only caps
cla;
superbar(Y, 'E', E, 'ErrorbarStyle', '=');

%% ... other styles can be set for SUPERBAR - only upward cap
cla;
superbar(Y, 'E', E, 'ErrorbarStyle', '_');


%% Customising errorbar linewidths
clf;

Y = [11 15 12.5 9  ];
E = [ 3  4  2   1.5];

% Plot with bar
subplot(1, 2, 1);
hold on;
bar(Y);
h = errorbar(1:numel(Y), Y(:), zeros(size(E)), E, '.', 'MarkerSize', 1, ...
    'LineWidth', 5);
title('bar');

% Plot with superbar
subplot(1, 2, 2);
superbar(Y, 'E', E, 'ErrorbarStyle', 'T', 'ErrorbarLineWidth', 5);
title('superbar');

% Error bars created using BAR can't be customised, whereas SUPERERR can,
% and the parameters for this can be conveniently set when calling
% SUPERBAR.

%% ... parameters of the error bar can be set - cap width
cla;
superbar(Y, 'E', E, 'ErrorbarStyle', 'T', 'ErrorbarRelativeWidth', 0.8);


%% ========================================================================
%. (3) Bars with errors and p-values
%. ========================================================================

% In this section, we describe how SUPERBAR can be used to plot bars with
% errors which have p-values attached to them. Since it is not possible to
% do this using only bultin MATLAB functions (that is to say, without
% completely reimplementing SUPERBAR), we will not be drawing comparisons
% with BAR. Instead we showcase the features of SUPERBAR alone.

%% Bar with errorbar and p-values
clf;

Y = [9   11    15    10    12.5    13.5    ];
E = [5    4     2    1      0.75    0.3    ];
P = [0.4  0.19  0.04 0.009  0.0009  0.00009];

% Plot with superbar
superbar(Y, 'E', E, 'P', P);
title('Bars with errors and p-value significance');

% Using P as a matrix the same shape as Y, we can define p-values for the
% significance of the measurement indicated by each bar. This will be
% indicated with stars above the bars.

%% ... changing the threshold for stars

% Plot with superbar
superbar(Y, 'E', E, 'P', P, 'PStarThreshold', [0.05 0.01 0.001]);
title('Bars with errors and p-value significance');

%% ... showing an extra star instead of a greater-than sign

% Plot with superbar
superbar(Y, 'E', E, 'P', P, 'PStarShowGT', false);
title('Bars with errors and p-value significance');

% And if you wanted to only go up to 3 stars and never use a greater sign,
% simply combine both of these modifiers as they are above.


%% Significance indicators can be combined with other SUPERBAR features
clf;

Y = [ 9 14 -10;
     15 -4  16];
E = [ 4  0.75  1  ;
      2  5     1.5];
P = [0.10  0.0008 0.01;
     0.04  0.2    0.03];
C = [.8 .2 .8;
     .2 .75 .2];

superbar(Y, 'E', E, 'P', P, 'BarFaceColor', C);
title('Grouped coloured bars with errors and significance');

% You can, of course, combine this with any of the features mentioned
% above, such as colouring the bars individually and using a different
% errorbar style.
% And the bars can be negative, in which case the text for the stars is
% show underneath instead of above the bars.

%% Pair-wise comparisons between bars
clf;

Y = [11 14 13;
     15 12 16];
E = [ 3  4  2;
      5  2  3];
C = [.8 .2 .2;
     .2 .2 .8];

P = [NaN    NaN    0.1    NaN     0.051  NaN    ;
     NaN    NaN    NaN    0.05    NaN    0.049  ;
     0.1    NaN    NaN    NaN     0.0005 NaN    ;
     NaN    0.05   NaN    NaN     NaN    0.00005;
     0.051  NaN    0.0005 NaN     NaN    NaN    ;
     NaN    0.049  NaN    0.00005 NaN    NaN    ];

[hb, he, hpt, hpl, hpb] = superbar(Y, 'E', E, 'P', P, 'BarFaceColor', C);
xlim([0.5 2.5]);

% If P is a square matrix containing NUMEL(Y) many rows and columns, the
% p-values are interpretted as the significance of comparisons between each
% pair of bars.
% Please note that the matrix P must be symmetric! This is because a single
% line between bar i and bar j will be drawn, so the element P(i,j) must
% always equal P(j,i). Testing P to make sure it is symmetric also provides
% a sanity-check on the input, since a badly formatted P is likely to be
% asymmetric.
% Also note that the diagonal must consist of NaNs, because comparisons
% cannot be drawn from a bar to itself.
% Lines are drawn for every non-NaN P-value, regardless of whether it is
% significant. The significance is then indicated above each comparison
% line.

% The order for comparisons is the same as when Y is flattened - first
% element 1 in group 1, then element 1 in group 2, then element 2 in group
% 1, etc. Note that this is *not* the same as the order in which the bars
% appear when they are plotted, since bars are plotted one group at a time.

% In this example, we restricted ourselves to only drawing comparisons
% within groups, which was 6 comparisons. This is not necessary, but the
% number of lines plotted will become very large if many comparisons are
% drawn (as it rightly should do).


%% with pair-wise comparison p values
clear all;
clf;

Y = [11 14 13;
     15 12 16];
E = [ 3  4  2;
      5  2  3];
C = [.8 .2 .2;
     .2 .2 .8];
 
P = nan(numel(Y), numel(Y));
P(1,2) = 0.1;
P(3,4) = 0.05;
P(5,6) = 0.01;
% Make P symmetric, by copying the upper triangle onto the lower triangle
PT = P';
lidx = tril(true(size(P)), -1);
P(lidx) = PT(lidx);

superbar(Y, 'E', E, 'P', P, 'BarFaceColor', C);
xlim([0.5 2.5]);

% Here we drawn comparisons between groups, but only for the same element
% index with each group.

% Note that in the code here, we entered p-values for the three lines and
% then copied the upper triangle of the matrix onto the lower triangle.


%% Bars with pair-wise comparison p values
clf;

Y = 10 * rand([3 2]);
C = [.8 .2 .2;
     .2 .2 .8;
     .8 .8 .2];

pvals = 0.25 * rand((numel(Y) * (numel(Y)-1))/2, 1);
P = nan(numel(Y), numel(Y));
% Fill in upper triangle of P
uidx = triu(true(size(P)),  1);
P(uidx) = pvals;
% Make P symmetric, by copying the upper triangle onto the lower triangle
lidx = tril(true(size(P)), -1);
PT = P';
P(lidx) = PT(lidx);

superbar(Y, 'P', P, 'BarFaceColor', C);

% If you really want, you can add lots of comparisons. But I hope you've
% done a Bonferroni correction or something similar to correct for the
% amount of comparisons you're doing, since otherwise some of them will
% inevitably be significant simply by chance.
% If you've got to the point where its hard to see all the lines, have a
% serious think about why you're comparing so many things with each other!
% It's generally not good statistical practice.


%% Making the SUPERBAR logo

hf = figure('Position', [100 100 550 400]);

Y = [ 6 14;
     17 12];
E = [ 3  1;
      5  2];

C = [
    0.90    0.55    0.55
    0.62    0.76    0.84
    0.89    0.10    0.11
    0.12    0.47    0.70
    ];
C = reshape(C, [2 2 3]);

P = nan(numel(Y), numel(Y));
P(1,2) = 0.04;
P(1,3) = 0.004;
P(2,4) = 0.10;
P(3,4) = 0.10;
% Make P symmetric, by copying the upper triangle onto the lower triangle
PT = P';
lidx = tril(true(size(P)), -1);
P(lidx) = PT(lidx);

superbar(Y, 'E', E, 'P', P, 'BarFaceColor', C, 'Orientation', 'v', ...
    'ErrorbarStyle', 'T', 'PLineOffset', 3);

% Need to change fontsize

xlim([0.5 2.5]);
ylim([0 32]);

set(gca, 'XTick', []);
set(gca, 'YTick', []);

% export_fig('images/logo', '-eps', '-png', '-painters');

% Future feature: put A1 A2 B1 B2 on the x axis at the correct places. This
% needs X to be returned by SUPERBAR.
